<?php
/**
 * Created by PhpStorm.
 * User: qinpeizhou
 * Date: 2018年5月27日
 * Time: 11:21:25
 * Websock_server基于http_server所以也有http的内容
 */
class Ws
{
    public static $instance;

    public $ws = null;
    public static $get;        
    public static $post;
    public static $files;
    public static $header;
    public static $server;
    private $application;

    public function __construct() {
        $this->ws = new swoole_websocket_server("0.0.0.0", 8811);
        $this->ws->listen("0.0.0.0", 8812,SWOOLE_SOCK_TCP);

        $this->ws->set(
            array(
                'enable_static_handler'=>true,
                'document_root'=> '/home/wwwroot/default/yafdemo/public/static',
                'worker_num' => 4,  // 开启的进程数
                'task_worker_num' => 4
//                'daemonize' => true,
//                'max_request' => 10000,
//                'dispatch_mode' => 1
            )
        );

        $this->ws->on("start", [$this, 'onStart']);
        $this->ws->on("open", [$this, 'onOpen']);
        $this->ws->on("message", [$this, 'onMessage']);
        $this->ws->on("workerstart", [$this, 'onWorkerStart']);
        $this->ws->on("request", [$this, 'onRequest']);
        $this->ws->on("task", [$this, 'onTask']);
        $this->ws->on("finish", [$this, 'onFinish']);
        $this->ws->on("close", [$this, 'onClose']);

        $this->ws->start();
    }



    /**
     * @param $server
     */
    public function onStart($server) {
        swoole_set_process_name("live_master");
    }
    public function onWorkerStart($server,  $worker_id) {
        Yaf_Loader::import(dirname(__FILE__).'/../common/lib/Task.php');
        define('APPLICATION_PATH', dirname(__DIR__));
        $this->application = new Yaf_Application( APPLICATION_PATH .
            "/conf/application.ini");
        ob_start();
        $this->application->bootstrap()->run();
        ob_end_clean();
    }

    public function onRequest($request, $response) {
        if($request->server['request_uri'] == '/favicon.ico') {
            $response->status(404);
            $response->end();
            return ;
        }
        // 转换成原生php
        $_SERVER  =  [];
        if(isset($request->server)) {
            Ws::$server =  $request->server;
            foreach($request->server as $k => $v) {
                Ws::$server[strtoupper($k)] = $v;
                $_SERVER[strtoupper($k)] = $v;
            }
        }
        if(isset($request->header)) {
            Ws::$header =  $request->header;
            foreach($request->header as $k => $v) {
                Ws::$server[strtoupper($k)] = $v;
                $_SERVER[strtoupper($k)] = $v;
            }
        }

        $_GET = [];
        if(isset($request->get)) {
            Ws::$get = $request->get;
            foreach($request->get as $k => $v) {
                Ws::$get[$k] = $v;
                $_GET[$k] = $v;
            }
        }
        $_POST = [];
        if(isset($request->post)) {
            Ws::$post = $request->post;
            foreach($request->post as $k => $v) {
                Ws::$post[$k] = $v;
                $_POST[$k] = $v;
            }
        }

        $_FILES = [];
        if(isset($request->files)) {
            Ws::$files = $request->files;
            foreach($request->files as $k => $v) {
                Ws::$files[$k] = $v;
                $_FILES[$k] = $v;
            }
        }

        Ws::$post['http_server'] = $this->ws;
        $_POST['http_server'] = $this->ws;

        ob_start();
        try {
            $yaf_request = new Yaf_Request_Http(Ws::$server['request_uri']);
            $this->application->getDispatcher()->dispatch($yaf_request);

//             unset(Yaf_Application::app());
        } catch ( Yaf_Exception $e ) {
            var_dump( $e );
        }


        $result = ob_get_contents();

        ob_end_clean();

        // add Header

        // add cookies

        // set status
        $response->end($result);
    }

    /**
     * @param $serv
     * @param $taskId
     * @param $workerId
     * @param $data
     */
    public function onTask($serv, $taskId, $workerId, $data) {
        // 分发 task 任务机制，让不同的任务 走不同的逻辑
        $method = $data['method'];
        $flag = Task::getInstance()->$method($data['data'],$serv);
        return $flag; // 告诉worker
    }

    /**
     * @param $serv
     * @param $taskId
     * @param $data
     */
    public function onFinish($serv, $taskId, $data) {
        echo "taskId:{$taskId}\n";
        echo "finish-data-sucess:{$data}\n";
    }

    /**
     * 监听ws连接事件
     * @param $ws
     * @param $request
     */
    public function onOpen($ws, $request) {
        // fd redis [1]
        Predis::getInstance()->sAdd(redis_config('live_game_key'), $request->fd);
        var_dump($request->fd);
    }

    /**
     * 监听ws消息事件
     * @param $ws
     * @param $frame
     */
    public function onMessage($ws, $frame) {
        echo "ser-push-message:{$frame->data}\n";
        $ws->push($frame->fd, "server-push:".date("Y-m-d H:i:s"));
    }

    /**
     * close
     * @param $ws
     * @param $fd
     */
    public function onClose($ws, $fd) {
        echo "clientid:{$fd}\n";
    }


    public static function getInstance() {
        if (!self::$instance) {
            self::$instance = new Ws;
        }
        return self::$instance;
    }

}

Ws::getInstance();
